﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ProjectDES
{
    public class Connection
    {
        public TcpClient tcpClient;
        private Thread thrSender;
        private StreamReader srReceiver;
        private StreamWriter swSender;
        public string currUser;
        public string currUserAdmin;
        private bool hasConnectedYet = false;
        private string strResponse;
        public Connection(TcpClient tcpCon)
        {
            tcpClient = tcpCon;
            thrSender = new Thread(AcceptClient);
            thrSender.Start();
        }
        public void CloseConnection()
        {
            if (hasConnectedYet)
            {
                if (Lists.OnlineAdmins.ContainsKey(currUser))
                {
                    Lists.OnlineAdmins.Remove(currUser);
                    ChatServer.SendAdminMessage("Room Admin " + currUser + " Left and Logged Out");
                }
                ChatServer.RemoveUser(tcpClient);
            }
            tcpClient.Close();
            srReceiver.Close();
            swSender.Close();
            thrSender.Abort();
        }
        private bool isValidNickname(string nick)
        {
            string AcceptedCharicters = Options.acceptedNicknameCharicters;
            bool isValid = true;
            char[] array = nick.ToCharArray();
            foreach (char c in array)
            {
                if (AcceptedCharicters.Contains(c.ToString())) { }
                else
                {
                    isValid = false;
                }
            }
            return isValid;
        }
        public void sendMessageToUser(string rawMessage)
        {
            swSender.WriteLine(rawMessage);
            swSender.Flush();
        }
        private void AcceptClient()
        {
            srReceiver = new System.IO.StreamReader(tcpClient.GetStream());
            swSender = new System.IO.StreamWriter(tcpClient.GetStream());
            currUser = srReceiver.ReadLine();
            if (currUser != "")
            {
                if (ChatServer.htUsers.Contains(currUser) == true)
                {
                    swSender.WriteLine("0|This nickname is in use.");
                    swSender.Flush();
                    CloseConnection();
                    return;
                }
                else if (currUser.ToLower() == "administrator" || currUser.ToLower() == "server" || currUser.ToLower() == "console" || currUser.ToLower() == "owner" || currUser.ToLower() == "admin")
                {
                    swSender.WriteLine("0|This nickname is unavailable.");
                    swSender.Flush();
                    CloseConnection();
                    return;
                }
                else if (isValidNickname(currUser) == false)
                {
                    swSender.WriteLine("0|This nickname contains invalid characters.");
                    swSender.Flush();
                    CloseConnection();
                    return;
                }
                else if (currUser.Length > Options.maxCharictersInNickname)
                {
                    swSender.WriteLine("0|This nickname has too many characters.");
                    swSender.Flush();
                    CloseConnection();
                    return;
                }
                else
                {
                    hasConnectedYet = true;
                    ChatServer.AddUser(tcpClient, currUser, this);
                    swSender.WriteLine("1");
                    swSender.Flush();
                    swSender.WriteLine("Welcome To The Network. Make Sure You Don't Spam");
                    swSender.WriteLine("--- You Have Successfully Connected ---");
                    swSender.Flush();
                }
            }
            else
            {
                CloseConnection();
                return;
            }

            try
            {
                while ((strResponse = srReceiver.ReadLine()) != "")
                {
                    if (strResponse == null)
                    {
                        CloseConnection();
                    }
                    else
                    {
                        ProcessMessage(strResponse);
                    }
                }
            }
            catch
            {
                CloseConnection();
            }
        }
        private void ProcessMessage(string rawMessage)
        {
            List<string> splitArray = new List<string>(rawMessage.Split(new char[] { ':' }));
            string command = splitArray[0];
            splitArray.RemoveAt(0);
            string message = String.Join(":", splitArray.ToArray());
            splitArray = new List<string>(command.Split(new char[] { ' ' }));
            command = splitArray[0];
            splitArray.RemoveAt(0);
            string[] commandArgs = splitArray.ToArray();

            if (command == "MSG")
            {
                ChatServer.OnCommand(Lists.MessageType.Message, currUser, message, commandArgs);
            }
            else if (command == "ACTION")
            {
                ChatServer.OnCommand(Lists.MessageType.Action, currUser, message, commandArgs);
            }
            else if (command == "ADMIN")
            {
                ChatServer.OnCommand(Lists.MessageType.AdminAction, currUser, message, commandArgs);
            }
            else if (command == "NOTICE")
            {
                ChatServer.OnCommand(Lists.MessageType.Notice, currUser, message, commandArgs);
            }
        }
    }
}
